﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using OAuthLib;
using WTwitter.Model.Framework;
using WTwitter.Model.Twitter.Utility;
using WTwitter.Model.Twitter;
using WTwitter.Model.Utility;
using WTwitter.Model.Twitter.Json;

namespace WTwitter.Model.UserData {
	public enum AuthState {
		Verified,
		FailedToVerify,
		NeverVerified,
	}

	/// <summary>
	/// ログイン情報を保持するクラス
	/// PublicフィールドはXmlSerializerによってファイルに保存される
	/// </summary>
	public class AuthInfo {
		public bool IsUseOAuth { get; set; }
		private AuthState _authState = AuthState.NeverVerified;

		#region Basic 認証用
		[XmlIgnore]
		public string Password { get; set; }//これは保存しない

		/// <summary>
		/// ユーザーID
		/// </summary>
		public string UserName { get; set; }

		/// <summary>
		/// ファイル保存用にエンコードしたパスワード
		/// </summary>
		public string PasswordEncoded {
			get {
				return Convert.ToBase64String(Encoding.ASCII.GetBytes(Password));
			}
			set {
				Password = Encoding.ASCII.GetString(Convert.FromBase64String(value));
			}
		}
		#endregion

		#region OAuth 認証用
		private AccessToken _accessToken; 
		[XmlIgnore]
		public AccessToken AccessToken {
			set {
				if (_accessToken != value) {
					_accessToken = value;
				}
			}
			get {
				if (_accessToken == null) {
					if (!string.IsNullOrEmpty(_accessTokenSecret) && !string.IsNullOrEmpty(_accessTokenValue)) {
						_accessToken = new AccessToken(_accessTokenValue, _accessTokenSecret);
					}
				}
				return _accessToken;
			}
		}

		private string _accessTokenSecret;
		//ファイルへの保存と読み込みにしか使用しない
		public string AccessTokenSecret {
			get {
				if (AccessToken == null) {
					return "";
				} else {
					return Convert.ToBase64String(Encoding.ASCII.GetBytes(AccessToken.TokenSecret));
				}
			}
			set {
				_accessTokenSecret = Encoding.ASCII.GetString(Convert.FromBase64String(value));
			}
		}

		//ファイルへの保存と読み込みにしか使用しない
		private string _accessTokenValue;
		public string AccessTokenValue {
			get {
				if (AccessToken == null) {
					return "";
				} else {
					return Convert.ToBase64String(Encoding.ASCII.GetBytes(AccessToken.TokenValue));
				}
			}
			set {
				_accessTokenValue = Encoding.ASCII.GetString(Convert.FromBase64String(value));
			}
		}

		#endregion

		/// <summary>
		/// ユーザー情報が入力されているかどうか
		/// ※OAuthの場合はAccessTokenをDLLでインスタンスを生成できない場合もEmpty扱いにする
		/// </summary>
		[XmlIgnore]
		public bool IsEmpty {
			get {
				if (IsUseOAuth) {
					if (AccessToken == null) {
						return false;
					} else {
						return true;
					}
				} else {
					if (string.IsNullOrEmpty(UserName) || string.IsNullOrEmpty(Password)) {
						return false;
					} else {
						return true;
					}
				}
			}
		}

		/// <summary>
		/// 認証情報の取得状況
		/// </summary>
		[XmlIgnore]
		public AuthState AuthState {
			get {
				return _authState;
			}
		}

		/// <summary>
		/// 認証情報をを検証する
		/// </summary>
		/// <returns>認証が通ったらtrue, 失敗したらfalse</returns>
		public bool VerifyCredential() {
			User user;
			try {
				 user = AccountMethod.VerifyCredential(this);
			} catch (AuthorizationFailedException) {
				_authState = AuthState.FailedToVerify;
				Message.Add(EventType.Error, "認証に失敗しました。アカウント情報を入力してください");
				return false;
			}
			this.User = new TwitterUser(user);
			_authState = AuthState.Verified;
			return true;
		}

		/// <summary>
		/// 認証アカウントのユーザー情報
		/// </summary>
		[XmlIgnore]
		public IUser User { get; private set; }

	}
}
